package com.csg.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.csg.entity.MediaManage;
import com.csg.enums.EventTypeEnums;
import com.csg.enums.RedisKeyEnums;
import com.csg.mapper.MediaManageMapper;
import com.csg.service.IMediaManageService;
import com.csg.util.RedisUtil;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author George Chan
 * @since 2019-11-24
 */
@Service
public class MediaManageServiceImpl extends ServiceImpl<MediaManageMapper, MediaManage> implements IMediaManageService {
    private static final Logger LOGGER = LoggerFactory.getLogger(MediaManageServiceImpl.class);
    private final RedisUtil redisUtil;

    @Autowired
    public MediaManageServiceImpl(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean syncData() {
        List<MediaManage> createList = Lists.newArrayList();
        List<MediaManage> updateList = Lists.newArrayList();
        List<String> deleteIds = Lists.newArrayList();

        // 一次同步数据数量最大值
        long size = redisUtil.getSyncSize();
        List<Object> list = redisUtil.getLeftList(RedisKeyEnums.RT_MEDIA_MANAGE.getKey(), size);
        LOGGER.info(" list ====》    {}", JSON.toJSONString(list));
        List<Map> mapList = JSONArray.parseArray(list.toString(), Map.class);

        mapList.stream().forEach(item -> {
            String eventType = (String) item.get("EventType");
            if (StringUtils.equalsIgnoreCase(eventType, EventTypeEnums.INSERT.getKey())) {
                MediaManage data = BeanUtil.mapToBean(item, MediaManage.class, true);
                DateTime dateTime = DateUtil.parse((String) item.get("unique_time"));
                long time = dateTime.toJdkDate().getTime();
                data.setId(time + (String) item.get("authorizeid"));
                createList.add(data);
            }
            if (StringUtils.equalsIgnoreCase(eventType, EventTypeEnums.UPDATE.getKey())) {
                MediaManage data = BeanUtil.mapToBean(item, MediaManage.class, true);
                DateTime dateTime = DateUtil.parse((String) item.get("unique_time"));
                long time = dateTime.toJdkDate().getTime();
                data.setId(time + (String) item.get("authorizeid"));
                updateList.add(data);
            }
            if (StringUtils.equalsIgnoreCase(eventType, EventTypeEnums.DELETE.getKey())) {
                DateTime dateTime = DateUtil.parse((String) item.get("unique_time"));
                long time = dateTime.toJdkDate().getTime();
                deleteIds.add(time + (String) item.get("authorizeid"));
            }
        });


        boolean flag;
        if (CollectionUtil.isNotEmpty(createList)) {
            flag = this.saveBatch(createList);
            if (!flag) {
                LOGGER.info("数据表 {} 执行同步 新增 失败， 数据为 ===》 {}", RedisKeyEnums.RT_MEDIA_MANAGE.getKey(), JSON.toJSONString(createList));
                throw new RuntimeException("rt_media_manage 数据同步失败");
            }
        }
        if (CollectionUtil.isNotEmpty(updateList)) {
            flag = this.updateBatchById(updateList);
            if (!flag) {
                LOGGER.info("数据表 {} 执行同步 新增 失败， 数据为 ===》 {}", RedisKeyEnums.RT_MEDIA_MANAGE.getKey(), JSON.toJSONString(updateList));
                throw new RuntimeException("rt_media_manage 数据同步失败");
            }
        }
        if (CollectionUtil.isNotEmpty(deleteIds)) {
            flag = this.removeByIds(deleteIds);
            if (!flag) {
                LOGGER.info("数据表 {} 执行同步 新增 失败， 数据为 ===》 {}", RedisKeyEnums.RT_MEDIA_MANAGE.getKey(), JSON.toJSONString(deleteIds));
                throw new RuntimeException("rt_media_manage 数据同步失败");
            }
        }
        flag = redisUtil.trimLeftList(RedisKeyEnums.RT_MEDIA_MANAGE.getKey(), list.size());
        if (!flag) {
            LOGGER.error("redis 清除key为==》 {}， 数量==》 {}  失败", RedisKeyEnums.RT_MEDIA_MANAGE.getKey(), list.size());
            throw new RuntimeException("清除redis数据失败!");
        }
        LOGGER.info("数据表 {} 同步成功, 操作数据 {} 条", RedisKeyEnums.RT_MEDIA_MANAGE.getKey(), list.size());
        return true;
    }
}
